<!-- Copyright (c) 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->

<link rel="import" href="cr-diff-image.html">
<link rel="import" href="cr-diff-messages.html">

<script src="../lib/highlight/highlight.pack.js"></script>
<script src="../lib/difflibjs/dist/difflib-browser.js"></script>

<polymer-element name="cr-diff" attributes="file active mode">
    <template>
        <link rel="stylesheet" href="cr-diff.css">
        <link rel="stylesheet" href="cr-diff-code-theme.css">
        <template if="{{ loading }}">
            <img src="../images/dots16.gif" class="spinner">
        </template>
        <div id="output" on-tap="{{ handleTap }}"></div>
    </template>
    <script>
        Polymer({
            publish: {
                active: { value: false, reflect: true },
            },
            created: function() {
                this.active = false;
                this.loading = false;
                this.file = null;
                this.mode = "unified";
                this.activeMode = "unified";
            },
            fileChanged: function(oldValue, newValue) {
                var output = this.$.output;
                if (output.firstChild)
                    output.innerHTML = "";
            },
            modeChanged: function(oldValue, newValue) {
                if (!this.active)
                    return;
                if (this.activeMode == this.mode)
                    return;
                // TODO(esprehn): Hiding the diff like this makes the page jump
                // to the top when toggling modes.
                this.hideDiff();
                this.showDiff();
            },
            handleTap: function(event) {
                var element = event.target;
                if (element.classList.contains("show-context")) {
                    this.showContext(element.line, element.section);
                }
            },
            showDiff: function() {
                var self = this;
                if (this.active)
                    return Promise.resolve(this);
                this.active = true;
                this.loading = true;
                this.activeMode = this.mode;
                return this.file.loadDiff().then(function(diff) {
                    self.loading = false;
                    if (!self.active)
                        return;
                    var builder = self.createDiffBuilder();
                    builder.emitDiff(diff);
                    self.asyncFire("diff-shown");
                }).catch(function(e) {
                    self.loading = false;
                    self.active = false;
                    console.log(e);
                });
            },
            hideDiff: function() {
                if (!this.active)
                    return Promise.resolve(this);
                this.active = false;
                this.$.output.innerHTML = "";
                this.asyncFire("diff-hidden");
                return Promise.resolve(this);
            },
            showContext: function(line, section) {
                var self = this;
                this.file.loadContext(line.contextLinesStart, line.contextLinesEnd).then(function(group) {
                    if (!section.parentNode)
                        return;
                    var builder = self.createDiffBuilder();
                    builder.emitGroup(group, section);
                    section.remove();
                    self.asyncFire("context-shown");
                }).catch(function(e) {
                    console.log(e);
                });
            },
            toggleDiff: function() {
                return this.active ? this.hideDiff() : this.showDiff();
            },
            createDiffBuilder: function() {
                if (this.activeMode == "unified")
                    return new DiffBuilderUnified(this.file, this.$.output);
                if (this.activeMode == "side-by-side")
                    return new DiffBuilderSideBySide(this.file, this.$.output);
                throw new Error("Invalid <cr-diff> mode.");
            },
        });
    </script>
</ploymer-element>
